/**
 * Copyright (C) 2010 Cloudfarming <info@cloudfarming.nl>
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.cloudfarming.sensor;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ServiceLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Base Receiver implementation, uses the service loader to discover the
 * parsers and handler available and use those to process the payloads.
 *
 * @author Timon Veenstra
 */
public abstract class ServiceLoaderReceiver implements Receiver {

    private static Log log = LogFactory.getLog(ServiceLoaderReceiver.class);

    @Override
    public void receive(Object payload) throws  NoSuchAlgorithmException, IOException{
        ServiceLoader<Parser> parserLoader = ServiceLoader.load(Parser.class);
        ServiceLoader<Handler> handlerLoader = ServiceLoader.load(Handler.class);

        loaders:
        for (Parser parser : parserLoader) {     
            try {
                if (parser.ableToParse(payload)) {
                    try {
                        ParsedUnit parsedUnit = parser.parse(payload);
                        for (Handler handler : handlerLoader) {
                            if (handler.canHandle(parsedUnit)) {
                                handler.handle(parsedUnit);
                            }
                        }
                        break loaders;
                    } catch (ParseException e) {
                        log.error("Exception while receiving." , e);
                    } catch (FileReadException e){
                        StringBuilder sb = new StringBuilder("File read Exception while parsing: ");
                        sb.append(payload.toString());
                        log.error(sb.toString() ,e);
                    }
                }
            } catch (AlreadyParsedException ex) {
                //Genuine!! move File?
                //TODO: [MERIJN] maak fiks dat hij de bestanden helemaal niet meer oppakt.
            }
        }
    }
}
